package com.speljohan.rsbot.account;

import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Pattern;

public class Account implements Comparable<Account> {
	private final Map<String, String> properties = new HashMap<String, String>(
			2);
	private String username, password;
	private final String usernameKey = "USERNAME", passwordKey = "PASSWORD";
	public static final Pattern VALID_USERNAME = Pattern
	.compile("[A-Za-z][A-Za-z0-9- _]*");

	public static boolean isValidKey(final String key) {
		return Account.VALID_USERNAME.matcher(key).matches();
	}

	public Account() {
		this(null, null);
	}

	public Account(final Map<String, String> property) {
		for (final String key : property.keySet()) {
			final String val = property.get(key);
			addProperty(key, val);
		}
	}

	public Account(final String username, final String password) {
		properties.put(usernameKey, username == null ? null : username
				.toLowerCase());
		this.username = username == null ? null : username.toLowerCase();
		properties.put(passwordKey, password);
		this.password = password;
	}

	public String addProperty(String key, String value) {
		key = key.toUpperCase();
		if (!Account.isValidKey(key)) {
			throw new RuntimeException("Invalid key: " + key);
		}
		if (key.equals(usernameKey)) {
			value = value.toLowerCase();
			username = value;
		} else if (key.equals(passwordKey)) {
			password = value;
		}
		return properties.put(key, value);
	}

	public int compareTo(final Account o) {
		return username.compareTo(o.username);
	}

	@Override
	public boolean equals(final Object obj) {
		if (!(obj instanceof Account)) {
			return false;
		}
		return username.equals(((Account) obj).username);
	}

	public Map<String, String> getAllProperties() {
		return Collections.unmodifiableMap(properties);
	}

	public Account getClean() {
		final Account a = new Account(properties);
		a.setPassword(null);
		return a;
	}

	public String getPassword() {
		return password;
	}

	public String getProperty(final String key) {
		return properties.get(key.toUpperCase());
	}

	public String getUsername() {
		return username;
	}

	@Override
	public int hashCode() {
		return username.hashCode();
	}

	public boolean isValid() {
		if (username == null || password == null) {
			return false;
		}
		return !username.isEmpty() && !password.isEmpty()
		&& Account.isValidKey(username);
	}

	public String setPassword(final String password) {
		this.password = password;
		return properties.put(passwordKey, password);
	}

	public String setUsername(final String username) {
		this.username = username.toLowerCase();
		return properties.put(usernameKey, username.toLowerCase());
	}

	@Override
	public String toString() {
		return username;
	}
}
